package com.eliza.rx.rxjava

import com.eliza.library.tools.InfoTools
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.core.Observer
import io.reactivex.rxjava3.disposables.Disposable
import org.reactivestreams.Subscriber
import org.reactivestreams.Subscription


/*-*- coding:utf-8 -*-
 * @Author  : debi
 * @Time    : 4/5/22
 * @Software: Android Studio
 */
class RxUse {
    /**
     * 创建被观察者 （Observable ）& 生产事件
     */
    fun createObservable() {
//        @NonNull ObservableOnSubscribe<T> source
//        事件源，被观察者。

        /**
         * 创建方法一
         */
        Observable.create<Int> { emitter ->
//             通过 ObservableEmitter类对象产生事件并通知观察者
            // a. 定义：事件发射器
            // b. 作用：定义需要发送的事件 & 向观察者发送事件
            emitter.onNext(1)
            emitter.onNext(2)
        }
        /**
         * 创建方法二
         */
        Observable.just("A", "B", "C");
        /**
         * 创建方法三
         */
        Observable.fromArray(arrayListOf(1, 2, 3))

    }


    /**
     * 创建观察者 （Observer ）并 定义响应事件的行为
     * */

    /**
     * <--方式1：采用Observer 接口 -->
     */
    fun createObserverI() {
//        <--方式1：采用Observer 接口 -->
        object : Observer<Int> {
            // 观察者接收事件前，默认最先调用复写 onSubscribe（）
            override fun onSubscribe(d: Disposable) {
                InfoTools.LogTools(this, "=== createObserver --> onSubscribe")
            }

            // 当被观察者生产Next事件 & 观察者接收到时，会调用该复写方法 进行响应
            override fun onNext(t: Int) {
                InfoTools.LogTools(this, "=== createObserver --> onNext")

            }

            // 当被观察者生产Error事件& 观察者接收到时，会调用该复写方法 进行响应
            override fun onError(e: Throwable) {
                InfoTools.LogTools(this, "=== createObserver --> onError")

            }

            // 当被观察者生产Complete事件& 观察者接收到时，会调用该复写方法 进行响应
            override fun onComplete() {
                InfoTools.LogTools(this, "=== createObserver --> onComplete")

            }


        }

    }


    /**
     * <--方式2：采用Subscriber 抽象类 -->
    // 说明：Subscriber类 = RxJava 内置的一个实现了 Observer 的抽象类，对 Observer 接口进行了扩展

     */
    fun createSubscriber() {
//        <--方式1：采用Observer 接口 -->
        object : Subscriber<Int> {
            override fun onSubscribe(s: Subscription?) {
                InfoTools.LogTools(this::class.java.name, "开始采用subscribe连接")
            }

            override fun onNext(value: Int?) {
                InfoTools.LogTools(this::class.java.name, "对Next事件作出响应:: $value")

            }

            override fun onError(t: Throwable?) {
                InfoTools.LogTools(this::class.java.name, "对Error事件作出响应")

            }

            override fun onComplete() {
                InfoTools.LogTools(this::class.java.name, "对Complete事件作出响应")

            }


        }

    }

    /**
     * 通过订阅（Subscribe）连接观察者和被观察者
     */
    fun linkSubscribe() {
        Observable.fromArray(arrayListOf(1, 2, 3))
            .subscribe()
    }


    /**
     * 常用，真正 链式使用
     */

    fun chainRxjava() {
        Observable.create<Int> { e ->
            e.onNext(1)
            e.onNext(2)
            e.onNext(3)

        }
            .subscribe(object : Observer<Int> {
                // 观察者接收事件前，默认最先调用复写 onSubscribe（）
                override fun onSubscribe(d: Disposable) {
                    InfoTools.LogTools(this, "=== createObserver --> onSubscribe")
                }

                // 当被观察者生产Next事件 & 观察者接收到时，会调用该复写方法 进行响应
                override fun onNext(t: Int) {
                    InfoTools.LogTools(this, "=== createObserver --> onNext")

                }

                // 当被观察者生产Error事件& 观察者接收到时，会调用该复写方法 进行响应
                override fun onError(e: Throwable) {
                    InfoTools.LogTools(this, "=== createObserver --> onError")

                }

                // 当被观察者生产Complete事件& 观察者接收到时，会调用该复写方法 进行响应
                override fun onComplete() {
                    InfoTools.LogTools(this, "=== createObserver --> onComplete")

                }

            })

    }

//注：整体方法调用顺序：观察者.onSubscribe（）> 被观察者.subscribe（）> 观察者.onNext（）>观察者.onComplete()
}
